﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace VideoLink.Utility
{
    /// <summary>
    /// Класс, осуществляющий логгирование сообщений в указанный TextBox.
    /// Экземпляры данного класса потокобезопасны.
    /// Реализован шаблон проектирования "Одиночка".
    /// </summary>
    public sealed class DebugLog
    {
        #region Static members

        /// <summary>
        /// Текущий экземпляр класса
        /// </summary>
        private static DebugLog log = null;

        /// <summary>
        /// Текущий экземпляр класса
        /// </summary>
        public static DebugLog Instance
        {
            get { return log; }
        }

        /// <summary>
        /// Создать экземпляр логгера
        /// </summary>
        /// <param name="parent">
        /// Контрол, на который будет осуществляться вывод сообщений.
        /// </param>
        public static void Initialize(TextBox parent)
        {
            if (log == null)
                log = new DebugLog(parent);
        }
        
        #endregion

        #region Private members

        /// <summary>
        /// Контрол, на который осуществляется вывод сообщений.
        /// </summary>
        private TextBox parent;

        /// <summary>
        /// Создать новый экземпляр класса с указанным родительским контролом.
        /// </summary>
        /// <param name="parent">
        /// Контрол, на который будет осуществляться вывод сообщений.
        /// </param>
        private DebugLog(TextBox parent)
        {
            this.parent = parent;
        }
        
        #endregion

        #region Public methods

        /// <summary>
        /// Вывести в лог строку. Символ новой строки будет добавлен автоматически.
        /// </summary>
        /// <param name="message">
        /// Сообщение для вывода.
        /// </param>
        public void WriteLine(string message)
        {
            if (parent == null)
                return;

            parent.BeginInvoke(new Action(() =>
                {
                    parent.Text += message + Encoding.Default.GetString(new byte[] { 13, 10 });
                    parent.SelectionStart = parent.Text.Length - 1;
                    parent.ScrollToCaret();
                }));
        }

        /// <summary>
        /// Вывести в лог строку. К сообщению будет приписано время вызова данного метода.
        /// </summary>
        /// <param name="message">
        /// Сообщение для вывода.
        /// </param>
        public void WriteWithTime(string message)
        {
            WriteLine(message + " "
                + DateTime.Now.ToString("mm_ss_ffffff"));
        }
        
        #endregion
    }
}
